package com.flyduck.vueshop.order.admin.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.flyduck.vueshop.common.core.exception.BusinessException;
import com.flyduck.vueshop.common.core.utils.BeanUtils;
import com.flyduck.vueshop.common.core.utils.StringUtils;
import com.flyduck.vueshop.order.constant.OrderConstant;
import com.flyduck.vueshop.order.admin.service.AdminRefundService;
import com.flyduck.vueshop.order.admin.vo.*;
import com.flyduck.vueshop.order.entity.AppOrder;
import com.flyduck.vueshop.order.entity.AppOrderItem;
import com.flyduck.vueshop.order.entity.AppRefund;
import com.flyduck.vueshop.order.manager.AppPayManager;
import com.flyduck.vueshop.order.mapper.AppOrderItemMapper;
import com.flyduck.vueshop.order.mapper.AppOrderMapper;
import com.flyduck.vueshop.order.mapper.AppRefundMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * AdminRefundServiceImpl
 * </p>
 *
 * @author flyduck
 * @since 2024-06-13
 */
@Service
public class AdminRefundServiceImpl implements AdminRefundService {

    @Resource
    private AppRefundMapper appRefundMapper;
    @Resource
    private AppOrderMapper appOrderMapper;
    @Resource
    private AppPayManager appPayManager;
    @Resource
    private AppOrderItemMapper appOrderItemMapper;

    @Override
    public List<AdminDictRespVO> getRefundStatusList() {
        List<AdminDictRespVO> adminDictRespVOList = new ArrayList<>();
        for (OrderConstant.RefundStatus refundStatus : OrderConstant.RefundStatus.values()) {
            AdminDictRespVO adminDictRespVO = new AdminDictRespVO();
            adminDictRespVO.setKey(refundStatus.getCode());
            adminDictRespVO.setValue(refundStatus.getDescription());
            adminDictRespVOList.add(adminDictRespVO);
        }
        return adminDictRespVOList;
    }

    @Override
    public Page<AdminRefundRespVO> getRefundPage(Page page, AdminRefundQueryReqVO adminRefundQueryReqVO) {
        return appRefundMapper.getRefundPage(page,adminRefundQueryReqVO);
    }

    @Override
    public AdminRefundDetailsRespVO getRefundDetailsById(Long id) {
        AdminRefundDetailsRespVO adminRefundDetailsRespVO = new AdminRefundDetailsRespVO();

        //退货
        AppRefund appRefund = appRefundMapper.selectById(id);
        AdminRefundDetailsRespVO.AppRefundVO appRefundVO = BeanUtils.toBean(appRefund, AdminRefundDetailsRespVO.AppRefundVO.class);
        adminRefundDetailsRespVO.setRefund(appRefundVO);

        //订单
        AppOrder appOrder = appOrderMapper.selectById(appRefund.getOrderId());
        List<AppOrderItem> appOrderItemList = appOrderItemMapper.getAppOrderItemListByOrderId(appOrder.getId());
        AdminRefundDetailsRespVO.AppOrderVO appOrderVO = BeanUtils.toBean(appOrder, AdminRefundDetailsRespVO.AppOrderVO.class);
        List<AdminRefundDetailsRespVO.AppOrderItemVO> appOrderItemVOList = BeanUtils.toBeanList(appOrderItemList, AdminRefundDetailsRespVO.AppOrderItemVO.class);
        appOrderVO.setOrderItems(appOrderItemVOList);
        adminRefundDetailsRespVO.setOrder(appOrderVO);

        return adminRefundDetailsRespVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void auditRefund(AdminRefundAuditReqVO adminRefundAuditReqVO) {
        AppRefund appRefund = appRefundMapper.selectById(adminRefundAuditReqVO.getId());
        AppOrder appOrder = appOrderMapper.selectById(appRefund.getOrderId());

        if (OrderConstant.RefundStatus.PROCESSING.getCode() == adminRefundAuditReqVO.getRefundStatus() //退货中
                || OrderConstant.RefundStatus.REJECTED.getCode() == adminRefundAuditReqVO.getRefundStatus()) {//拒绝退货
            if(OrderConstant.RefundStatus.PENDING.getCode() != appRefund.getRefundStatus()){
                throw new BusinessException("状态异常");
            }

            if(adminRefundAuditReqVO.getRefundAmount() == null || StringUtils.isBlank(adminRefundAuditReqVO.getOperateRemark())){
                throw new BusinessException("退款金额或处理备注不能为空");
            }

            if(adminRefundAuditReqVO.getRefundAmount().compareTo(appOrder.getTotalAmount()) > 0){
                throw new BusinessException("退款金额不能大于订单总金额");
            }

            appRefund.setRefundAmount(adminRefundAuditReqVO.getRefundAmount());
            appRefund.setRefundStatus(adminRefundAuditReqVO.getRefundStatus());
            appRefund.setOperateRemark(adminRefundAuditReqVO.getOperateRemark());
            appRefund.setOperatorId(StpUtil.getLoginIdAsLong());
            appRefund.setOperateTime(LocalDateTime.now());

            //如果是拒绝
            if(OrderConstant.RefundStatus.REJECTED.getCode() == adminRefundAuditReqVO.getRefundStatus()){
                appOrder.setOrderStatus(OrderConstant.OrderStatus.REFUND_FAILED.getCode());
                appOrderMapper.updateById(appOrder);
            }

        }else if(OrderConstant.RefundStatus.COMPLETED.getCode() == adminRefundAuditReqVO.getRefundStatus()){//确认退货退款
            if(OrderConstant.RefundStatus.PROCESSING.getCode() != appRefund.getRefundStatus()){//必须是退货中
                throw new BusinessException("状态异常");
            }

            if(StringUtils.isBlank(adminRefundAuditReqVO.getReceiptRemark())){
                throw new BusinessException("处理备注不能为空");
            }

            appRefund.setReceiptRemark(adminRefundAuditReqVO.getReceiptRemark());
            appRefund.setRefundStatus(adminRefundAuditReqVO.getRefundStatus());


            appOrder.setOrderStatus(OrderConstant.OrderStatus.REFUNDED.getCode());
            appOrder.setRefundTime(LocalDateTime.now());
            appOrderMapper.updateById(appOrder);

            //退款处理
            appPayManager.refund(appRefund.getId());
        }
        appRefund.setUpdated(LocalDateTime.now());
        appRefundMapper.updateById(appRefund);
    }
}
